package com.oneinlet

import java.io.File
import java.time.LocalDateTime
import java.util.*
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.close
import java.util.zip.ZipEntry
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream
import java.util.zip.ZipOutputStream
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.close
import java.util.Enumeration
import java.util.zip.ZipFile
import com.sun.org.apache.bcel.internal.classfile.JavaClass.ZIP
import java.io.IOException
import org.omg.CORBA.UNKNOWN
import com.sun.org.apache.bcel.internal.classfile.JavaClass.ZIP


/**
 * Created by WangZiHe on 2018/5/19
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */

/**
 * 文件助手，帮助你创建文件，递归删除文件，追加文本，新建文件，压缩文件，解压文件，监控文件
 * */
object YCFile {

    /*
    *  文件分隔符，自动识别不同操作系统的分隔符
    * */
    private val separator = File.separator

    /**
     * 创建文件，该文件会自动创建上级路径,有效解决文件路径存在多个不存在上级目录的问题
     * @param path  指定文件路径
     * @return  返回一个文件对象
     * */
    fun createFile(path: String): File {
        val file = File(path)
        if (!file.exists()) {
            file.mkdirs()
        }
        return file
    }

    /**
     * 创建模版文件，使用前缀+时间日期+后缀格式的文件命名方式，方便记录文件路径，适合存储网站上传文件
     * @param path  指定文件路径
     * @param prefix  指定文件前缀
     * @param suffix  指定文件后缀格式 例如 .txt .jpg
     * @return  返回一个文件对象
     * */
    fun createTemplateFile(path: String, prefix: String? = null, suffix: String): File {
        val localDate = LocalDateTime.now()
        val year = localDate.year
        val month = localDate.month.value
        val time = YCDate.formatDate(Date(), YCDate.DateFormat.YYYYMMDDHHMMSS)
        val sb = StringBuilder(path)
        sb.append(separator).append(year)
                .append(separator).append(month).append(separator)
        createFile(sb.toString())
        if (prefix != null) {
            sb.append(prefix)
        }
        sb.append(time).append(suffix)
        val file = File(sb.toString())
        if (!file.exists()) {
            file.createNewFile()
        }
        return file
    }


    /**
     * 删除文件，会删除该路径下多级目录的所有文件，回收站无法找回，请谨慎使用！！！
     * @param path  指定目录路径
     * */
    fun deleteAll(path: String) {
        val file = File(path)
        if (file.isDirectory) {
            println("当前删除目录： ${file.path}")
            val files = file.listFiles()
            for (f in files) {
                deleteAll(f.path)
            }
        }
        file.delete()
        println("当前删除文件： ${file.path}")
    }

    /**
     * 压缩文件，支持单个文件或多级目录
     * @param resourcePath  需要压缩的资源文件路径，必须文件夹路径 后面不要带文件分隔符，如  c:/abc
     * @param zipPath  压缩文件存放位置
     * */
    fun compressZIP(resourcePath: String, zipPath: String) {
        // zip文件输出流
        val zipOut = ZipOutputStream(FileOutputStream(File(zipPath)))
        val resourceFile = File(resourcePath)
        // 如果指定的资源文件路径是文件夹
        if (!resourceFile.isDirectory) {
            throw RuntimeException("请指定 resourcePath参数 资源文件路径为文件夹")
        }
        val files = resourceFile.listFiles()
        for (fileSec in files!!) {
            recursionZip(zipOut, fileSec, resourceFile.name + File.separator)
        }
        zipOut.close()
    }

    private fun recursionZip(zipOut: ZipOutputStream, file: File, baseDir: String) {
        // 判断文件是否是目录
        if (file.isDirectory) {
            //获取该目录下的所有文件
            val files = file.listFiles()
            for (fileSec in files!!) {
                recursionZip(zipOut, fileSec, baseDir + file.name + File.separator)
            }
        } else {
            val input = FileInputStream(file)
            val zipEntry = ZipEntry(baseDir + file.name)
            zipOut.putNextEntry(zipEntry)
            YCStream.write(input, zipOut)
            input.close()
        }
    }


    /**
     * 解压zip格式文件
     *
     * @param originFile zip文件。
     * @param targetDir  要解压到的目标路径。
     * @return 如果目标文件不是zip文件则返回false。
     */
    fun decompressZIP(originFilePath: String, targetDir: String): Boolean {
        var targetPath = targetDir
        if (!targetPath.endsWith(File.separator)) {
            targetPath += File.separator
        }
        createFile(targetPath)
        val zipFile = ZipFile(File(originFilePath))
        var zipEntry: ZipEntry
        val entry = zipFile.entries()
        while (entry.hasMoreElements()) {
            zipEntry = entry.nextElement()
            val fileName = zipEntry.name
            val outputFile = File(targetPath + fileName)
            if (zipEntry.isDirectory) {
                if (!outputFile.exists()) {
                    outputFile.mkdirs()
                }
                continue
            } else if (!outputFile.parentFile.exists()) {
                createFile(outputFile.parent)
            }
            val outputStream = FileOutputStream(outputFile)
            val inputStream = zipFile.getInputStream(zipEntry)
            YCStream.write(inputStream, outputStream)
            outputStream.close()
            inputStream.close()
        }
        zipFile.close()
        return true
    }

    /**
     * 获取文件名的后缀标识 如 .txt  .jpg
     * @param fileName 文件名
     * @return 返回文件的后缀名标识
     */
    fun getFileSuffix(fileName: String): String {
        val index = fileName.lastIndexOf('.')
        if (-1 == index) {
            throw RuntimeException("未找到点后缀，正确的文件名应该是 name.txt，传入的文件名：$fileName 未发现")
        }
        return fileName.substring(index)
    }


}